home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / comms / other / slrn / slrn_src / src / server.c < prev    next >
C/C++ Source or Header  |  1999-05-14  |  13KB  |  650 lines

  1. /* Copyright (c) 1998 John E. Davis (davis@space.mit.edu)
  2.  *
  3.  * This file is part of slrn.
  4.  *
  5.  * Slrn is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License as published by the
  7.  * Free Software Foundation; either version 2, or (at your option) any
  8.  * later version.
  9.  * 
  10.  * Slrn is distributed in the hope that it will be useful, but WITHOUT
  11.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13.  * for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with Slrn; see the file COPYING.  If not, write to the Free
  17.  * Software Foundation, 59 Temple Place - Suite 330, 
  18.  * Boston, MA  02111-1307, USA.
  19.  */
  20.  
  21. #include "config.h"
  22. #include "slrnfeat.h"
  23.  
  24. #include <stdio.h>
  25.  
  26. #ifdef HAVE_STDLIB_H
  27. # include <stdlib.h>
  28. #endif
  29.  
  30. #include <slang.h>
  31. #include "jdmacros.h"
  32.  
  33. #include "slrn.h"
  34. #include "server.h"
  35. #include "misc.h"
  36. #include "util.h"
  37. #include "startup.h"
  38. #if SLRN_USE_SLTCP 
  39. # if SLRN_HAS_NNTP_SUPPORT || SLRN_HAS_GROUP_LENS
  40. #  include "sltcp.h"
  41. #  include "sltcp.c"
  42. # endif
  43. #endif
  44.  
  45. #if SLRN_HAS_NNTP_SUPPORT
  46. # if !SLRN_USE_SLTCP
  47. #  include "clientlib.c"
  48. # endif
  49. # include "nntplib.c"
  50. # include "nntp.c"
  51. #endif
  52.  
  53. #if SLRN_HAS_SPOOL_SUPPORT
  54. # include "spool.c"
  55. #endif
  56.  
  57. int Slrn_Server_Id;
  58. int Slrn_Post_Id;
  59.  
  60. Slrn_Server_Obj_Type *Slrn_Server_Obj;
  61. Slrn_Post_Obj_Type *Slrn_Post_Obj;
  62.  
  63. #if SLRN_HAS_PULL_SUPPORT
  64. static int pull_init_objects (void);
  65. static int pull_select_post_object (void);
  66. static int pull_parse_args (char **, int);
  67. int Slrn_Use_Pull_Post;
  68. #endif
  69.  
  70. #if SLRN_HAS_INEWS_SUPPORT
  71. static FILE *Fp_Inews;
  72. char *Slrn_Inews_Pgm;
  73.  
  74. static int inews_start_post (void)
  75. {
  76.    /* pipe a message to inews. Its done this way because inews expects the
  77.     * article on stdin. Inews errors WILL mess up the screen.
  78.     */
  79.    /* !HACK! should we use slrn_popen() and slrn_pclose()?
  80.     * They stop the screen getting messed up, but the error messages aren't
  81.     * very appropriate
  82.     */
  83.    if (NULL == (Fp_Inews = popen (Slrn_Inews_Pgm, "w")))
  84.      {
  85.     slrn_error ("Couldn't open pipe to inews! -- Article not posted.");
  86.     return -1;
  87.      }
  88.    return CONT_POST;
  89. }
  90.  
  91. static int inews_end_post (void)
  92. {
  93.    int res = 0;
  94.    
  95.    if (-1 == pclose (Fp_Inews))
  96.      {
  97.     slrn_error ("pclose() failed -- check if article was posted"); /* !HACK! can we do better? */
  98.     res = -1;
  99.      }
  100.    Fp_Inews=NULL;
  101.    
  102.    return res;
  103. }
  104.  
  105. static int inews_puts (char *s)
  106. {
  107.    fputs (s, Fp_Inews );
  108.    return 0;
  109. }
  110.  
  111. static int inews_printf (char *fmt, ...)
  112. {
  113.    va_list ap;
  114.  
  115.    char buf [1024];
  116.    
  117.    va_start (ap, fmt);
  118.    vsprintf (buf, fmt, ap);
  119.    va_end (ap);
  120.    
  121.    return inews_puts(buf);
  122. }
  123.  
  124.  
  125. static Slrn_Post_Obj_Type Inews_Post_Obj;
  126.  
  127. static int inews_init_objects (void)
  128. {
  129.    Inews_Post_Obj.po_start = inews_start_post;
  130.    Inews_Post_Obj.po_end = inews_end_post;
  131.    Inews_Post_Obj.po_printf = inews_printf;
  132.    Inews_Post_Obj.po_puts = inews_puts;
  133.    Inews_Post_Obj.po_can_post = 1;
  134.    Slrn_Inews_Pgm = slrn_safe_strmalloc (SLRN_INEWS_PROGRAM);
  135.    return 0;
  136. }
  137.  
  138. static int inews_select_post_object (void)
  139. {
  140.    char inews [SLRN_MAX_PATH_LEN + 1];
  141.    char *p;
  142.    
  143.    strncpy (inews, Slrn_Inews_Pgm, SLRN_MAX_PATH_LEN);
  144.    inews[SLRN_MAX_PATH_LEN - 1] = 0;
  145.    
  146.    p = inews;
  147.    while (*p && (*p != ' ')) p++;
  148.    *p = 0;
  149.    
  150.    if (1 != slrn_file_exists (inews))
  151.      {
  152.     slrn_error ("Unable to locate inews program \"%s\"", inews);
  153.     return -1;
  154.      }
  155.    
  156.    Slrn_Post_Obj = &Inews_Post_Obj;
  157.    return 0;
  158. }
  159.  
  160. static void inews_usage (void)
  161. {
  162.    fputs ("--inews options:\n\
  163. ",
  164.       stdout);
  165.    exit (0);
  166. }
  167.  
  168. static int inews_parse_args (char **argv, int argc)
  169. {
  170.    int i;
  171.    
  172.    for (i = 0; i < argc; i++)
  173.      {
  174.     if (!strcmp (argv[i], "--help"))
  175.       inews_usage ();
  176.     else break;
  177.      }
  178.    
  179.    return i;
  180. }
  181.  
  182. #endif                       /* HAS_INEWS_SUPPORT */
  183.  
  184.  
  185. int slrn_init_objects (void)
  186. {
  187.    char *server;
  188.  
  189. #if SLRN_HAS_NNTP_SUPPORT
  190.    if (-1 == nntp_init_objects ())
  191.      return -1;
  192. #endif
  193. #if SLRN_HAS_SPOOL_SUPPORT
  194.    if (-1 == spool_init_objects ())
  195.      return -1;
  196. #endif
  197. #if SLRN_HAS_INEWS_SUPPORT
  198.    if (-1 == inews_init_objects ())
  199.      return -1;
  200. #endif
  201. #if SLRN_HAS_PULL_SUPPORT
  202.    if (-1 == pull_init_objects ())
  203.      return -1;
  204. #endif
  205.    
  206.    switch (Slrn_Server_Id)
  207.      {
  208.       case SLRN_SERVER_ID_NNTP:
  209.     server = "NNTP";
  210.     break;
  211.     
  212.       case SLRN_SERVER_ID_SPOOL:
  213.     server = "SPOOL";
  214.     break;
  215.     
  216.       default:
  217.     server = NULL;
  218.      }
  219.    
  220.    if ((server != NULL) 
  221.        && (-1 == SLdefine_for_ifdef (server)))
  222.      {
  223.     slrn_exit_error ("Unable to add preprocessor name %s.", server);
  224.      }
  225.    
  226.    return 0;
  227. }
  228.  
  229. #if !SLRN_HAS_INEWS_SUPPORT
  230. # undef SLRN_FORCE_INEWS
  231. # define SLRN_FORCE_INEWS 0
  232. #endif
  233.  
  234. int slrn_select_post_object (int id)
  235. {
  236.    char *post;
  237.  
  238.    switch (id)
  239.      {
  240. #if SLRN_HAS_INEWS_SUPPORT
  241.       case SLRN_POST_ID_INEWS:
  242. # if SLRN_HAS_PULL_SUPPORT
  243.     if (Slrn_Use_Pull_Post
  244.         && (Slrn_Server_Id == SLRN_SERVER_ID_SPOOL))
  245.       {
  246.          slrn_error ("inews cannot be used with an slrnpull spool.");
  247.          return -1;
  248.       }
  249. # endif
  250.     return inews_select_post_object ();
  251. #endif
  252.    
  253. #if !SLRN_FORCE_INEWS
  254. # if SLRN_HAS_NNTP_SUPPORT
  255.       case SLRN_POST_ID_NNTP:
  256.     return nntp_select_post_object ();
  257. # endif
  258. #endif
  259.     
  260. #if SLRN_HAS_PULL_SUPPORT
  261.       case SLRN_POST_ID_PULL:
  262.     return pull_select_post_object ();
  263. #endif
  264.  
  265.       default:
  266.     post = slrn_map_object_id_to_name (1, id);
  267.     if (post == NULL)
  268.       post = "UNKNOWN";
  269.  
  270.     slrn_error ("%s is not a supported posting agent.", post);
  271.      }
  272.    
  273.    return -1;
  274. }
  275.  
  276. int slrn_select_server_object (int id)
  277. {
  278. #if SLRN_HAS_SPOOL_SUPPORT
  279.    int ret;
  280. #endif
  281.    char *server;
  282.  
  283.    switch (id)
  284.      {
  285. #if SLRN_HAS_NNTP_SUPPORT
  286.       case SLRN_SERVER_ID_NNTP:
  287.     return nntp_select_server_object ();
  288. #endif
  289.     
  290. #if SLRN_HAS_SPOOL_SUPPORT
  291.       case SLRN_SERVER_ID_SPOOL:
  292.     ret = spool_select_server_object ();
  293.  
  294. # if SLRN_HAS_PULL_SUPPORT
  295.     if (ret == -1)
  296.       return ret;
  297.  
  298.     if (Slrn_Use_Pull_Post) 
  299.       Slrn_Post_Id = SLRN_POST_ID_PULL;
  300. # endif
  301.     return ret;
  302. #endif
  303.    
  304.       default:
  305.     server = slrn_map_object_id_to_name (0, id);
  306.  
  307.     if (server == NULL)
  308.       server = "UNKNOWN";
  309.  
  310.     slrn_error ("%s is not a supported server object.", server);
  311.      }
  312.    return -1;
  313. }
  314.  
  315. int slrn_parse_object_args (char *name, char **argv, int argc)
  316. {
  317.    int num_parsed = -1;
  318.  
  319.    if (name == NULL) return -1;
  320.    
  321.    if (!strcmp (name, "nntp"))
  322.      {
  323. #if SLRN_HAS_NNTP_SUPPORT
  324.     num_parsed = nntp_parse_args (argv, argc);
  325.     if (Slrn_Server_Id == 0)
  326.       Slrn_Server_Id = SLRN_SERVER_ID_NNTP;
  327. # if !SLRN_FORCE_INEWS
  328.     if (Slrn_Post_Id == 0)
  329.       Slrn_Post_Id = SLRN_POST_ID_NNTP;
  330. # endif
  331.     return num_parsed;
  332. #else
  333.     return -2;
  334. #endif
  335.      }
  336.    
  337.    if (!strcmp (name, "spool"))
  338.      {
  339. #if SLRN_HAS_SPOOL_SUPPORT
  340.     num_parsed = spool_parse_args (argv, argc);
  341.     Slrn_Server_Id = SLRN_SERVER_ID_SPOOL;
  342.     return num_parsed;
  343. #else
  344.     return -2;
  345. #endif
  346.      }
  347.    
  348.    if (!strcmp (name, "inews"))
  349.      {
  350. #if SLRN_HAS_INEWS_SUPPORT
  351.     num_parsed = inews_parse_args (argv, argc);
  352.     Slrn_Post_Id = SLRN_POST_ID_INEWS;
  353.     return num_parsed;
  354. #else 
  355.     return -2;
  356. #endif
  357.      }
  358.    
  359.    if (!strcmp (name, "pull"))
  360.      {
  361. #if SLRN_HAS_PULL_SUPPORT
  362.     num_parsed = pull_parse_args (argv, argc);
  363.     Slrn_Post_Id = SLRN_POST_ID_PULL;
  364.     return num_parsed;
  365. #else
  366.     return -2;
  367. #endif
  368.      }
  369.  
  370.    return num_parsed;
  371. }
  372.  
  373. typedef struct
  374. {
  375.    char *name;
  376.    int id;
  377. }
  378. Object_Name_Id_Type;
  379.  
  380. static Object_Name_Id_Type Server_Objects_and_Ids [] = 
  381. {
  382.    {"nntp", SLRN_SERVER_ID_NNTP},
  383.    {"spool", SLRN_SERVER_ID_SPOOL},
  384.    {NULL}
  385. };
  386.  
  387. static Object_Name_Id_Type Post_Objects_and_Ids [] = 
  388. {
  389.    {"nntp", SLRN_POST_ID_NNTP},
  390.    {"inews", SLRN_POST_ID_INEWS},
  391.    {"slrnpull", SLRN_POST_ID_PULL},
  392.    {NULL}
  393. };
  394.  
  395. /* These functions should not attempt to write any error messages */
  396. static Object_Name_Id_Type *map_object_type (int type, int *def_id)
  397. {
  398.    Object_Name_Id_Type *obj;
  399.    
  400.    switch (type)
  401.      {
  402.       case 0:
  403.     obj = Server_Objects_and_Ids;
  404.     if (def_id != NULL)
  405.       *def_id = SLRN_DEFAULT_SERVER_OBJ;
  406.     break;
  407.     
  408.       case 1:
  409.     obj = Post_Objects_and_Ids;
  410.     if (def_id != NULL)
  411.       *def_id = SLRN_DEFAULT_POST_OBJ;
  412.     break;
  413.     
  414.       default:
  415.     obj = NULL;
  416.      }
  417.    
  418.    return obj;
  419. }
  420.  
  421. char *slrn_map